/// <license>
/// This software and are provided as-is and without  warranty. 
/// This is  free  software,  as long  as you  clearly  display
/// the original author and his company for at least  1  second
/// on the attached display. If you need a commercial   license 
/// in which you do not have these restrictions, please contact
/// us via our website.
/// 
/// Author: Mario Di Vece
/// Unosquare S.A. de C.V. Copyright (c) 2013
/// url: http://www.unosquare.com
/// </license>

namespace Unosquare.Labs.Drivers.Vizic
{
    using Unosquare.Labs.Utils;

    /// <summary>
    /// Represents bte array with a 24-bit color convertible to a 16-bit color.
    /// </summary>
    public class VizicColor
    {
        byte[] m_Color = new byte[3];

        /// <summary>
        /// Initializes a new instance of the <see cref="VizicColor"/> class.
        /// </summary>
        public VizicColor() { }

        /// <summary>
        /// Initializes a new instance of the <see cref="VizicColor"/> class.
        /// </summary>
        /// <param name="red">The red.</param>
        /// <param name="green">The green.</param>
        /// <param name="blue">The blue.</param>
        public VizicColor(byte red, byte green, byte blue)
        {
            this.R = red;
            this.G = green;
            this.B = blue;
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="VizicColor"/> class.
        /// </summary>
        /// <param name="rgb">The RGB.</param>
        public VizicColor(byte[] rgb)
        {
            this.R = rgb[0];
            this.G = rgb[1];
            this.B = rgb[2];
        }

        /// <summary>
        /// Gets or sets the R.
        /// </summary>
        /// <value>
        /// The R.
        /// </value>
        public byte R { get { return m_Color[0]; } set { m_Color[0] = value; } }

        /// <summary>
        /// Gets or sets the G.
        /// </summary>
        /// <value>
        /// The G.
        /// </value>
        public byte G { get { return m_Color[1]; } set { m_Color[1] = value; } }

        /// <summary>
        /// Gets or sets the B.
        /// </summary>
        /// <value>
        /// The B.
        /// </value>
        public byte B { get { return m_Color[2]; } set { m_Color[2] = value; } }

        /// <summary>
        /// Gets the color.
        /// </summary>
        /// <value>
        /// The color.
        /// </value>
        public byte[] Color { get { return this.m_Color; } }

        /// <summary>
        /// Gets the color of the hi.
        /// </summary>
        /// <value>
        /// The color of the hi.
        /// </value>
        public byte[] HiColor
        {
            get
            {
                return ComputeHiColor(this.m_Color);
            }
        }

        static public byte[] ComputeHiColor(byte[] rgb, int offset = 0)
        {
            ushort hiColor = 0x0000;

            ushort rV = (ushort)((ushort)(rgb[offset + 0] * 31 / 255) << 11 & 0xF800);
            ushort gV = (ushort)((ushort)(rgb[offset + 1] * 63 / 255) << 5 & 0x07E0);
            ushort bV = (ushort)((ushort)(rgb[offset + 2] * 31 / 255) & 0x001F);

            hiColor = (ushort)(rV | gV | bV);
            return hiColor.ToByteArray();
        }

        #region Basic Color Names

        static public VizicColor Maroon { get { return new VizicColor(new byte[3] { 128, 0, 0 }); } }
        static public VizicColor Red { get { return new VizicColor(new byte[3] { 255, 0, 0 }); } }
        static public VizicColor Orange { get { return new VizicColor(new byte[3] { 255, 165, 0 }); } }
        static public VizicColor Yellow { get { return new VizicColor(new byte[3] { 255, 255, 0 }); } }
        static public VizicColor Olive { get { return new VizicColor(new byte[3] { 128, 128, 0 }); } }
        static public VizicColor Green { get { return new VizicColor(new byte[3] { 0, 128, 0 }); } }

        static public VizicColor Purple { get { return new VizicColor(new byte[3] { 128, 0, 128 }); } }
        static public VizicColor Fuchsia { get { return new VizicColor(new byte[3] { 255, 0, 255 }); } }
        static public VizicColor Lime { get { return new VizicColor(new byte[3] { 0, 255, 0 }); } }
        static public VizicColor Teal { get { return new VizicColor(new byte[3] { 0, 128, 128 }); } }
        static public VizicColor Aqua { get { return new VizicColor(new byte[3] { 0, 255, 255 }); } }
        static public VizicColor Blue { get { return new VizicColor(new byte[3] { 0, 0, 255 }); } }

        static public VizicColor Navy { get { return new VizicColor(new byte[3] { 0, 0, 128 }); } }
        static public VizicColor Black { get { return new VizicColor(new byte[3] { 0, 0, 0 }); } }
        static public VizicColor Gray { get { return new VizicColor(new byte[3] { 128, 128, 128 }); } }
        static public VizicColor Silver { get { return new VizicColor(new byte[3] { 192, 192, 192 }); } }
        static public VizicColor White { get { return new VizicColor(new byte[3] { 255, 255, 255 }); } }

        #endregion

    }
}
